#include "stdafx.h"
#include "BaseInc.h"

#include "Lion.h"
#include "buffer_simple.h"

const UINT_X WIDTH = 800;
const UINT_X HEIGHT = 600;
const CHAR_X CLASS_NAME[] = _T("class_xujie");
const CHAR_X WIND_NAME[] = _T("Test Venus Drawing");
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

HWND hWnd = NULL;
HINSTANCE hInst = NULL;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	//_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); 
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	hInst = hInstance;

	WNDCLASSEX wcex;
	wcex.cbSize			= sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= CLASS_NAME;
	wcex.hIconSm		= wcex.hIcon;

	RegisterClassEx(&wcex);

	hWnd = CreateWindowEx(0, CLASS_NAME, WIND_NAME, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL);

	MoveWindow(hWnd, 100, 100, WIDTH + 8, HEIGHT + 32, FALSE);
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

HDC hBmpDc = NULL;
HBITMAP hBmp = NULL;

action_t act;
countour_t ct;
shape_aa_t sp_aa;
scanline_aa_t scl_aa;
bool wire = false;

buffer_simple_t bs;

VOID OnCreate()
{
	HDC hdc = GetDC(NULL);
	BITMAPINFO bmpInfo = {0};
	bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmpInfo.bmiHeader.biWidth = WIDTH;
	bmpInfo.bmiHeader.biHeight = -((INT_32)HEIGHT);
	bmpInfo.bmiHeader.biPlanes = 1;
	bmpInfo.bmiHeader.biBitCount = 32;
	bmpInfo.bmiHeader.biCompression = BI_RGB;
	bmpInfo.bmiHeader.biSizeImage = WIDTH * HEIGHT * 4;
	uint_8 * bits = 0;
	hBmpDc = CreateCompatibleDC(NULL);
	hBmp = CreateDIBSection(hBmpDc, &bmpInfo, DIB_RGB_COLORS, (VOID **)&bits, NULL, 0);
	SelectObject(hBmpDc, hBmp);


	bs.pbits = bits;
	bs.length = bmpInfo.bmiHeader.biSizeImage;
	bs.width = WIDTH;
	bs.height = HEIGHT;
	bs.pitch = WIDTH << 2;
	bs.color = 0xFF000000;

	buffer_simple_initial(&bs);
	buffer_simple_set_gama(&bs, 1.00f);
	action_initial(&act);
	contour_initial(&ct);
	shape_aa_initial(&sp_aa);
	scanline_aa_initial(&scl_aa);

	act.anti = true;
	act.width = 1.0f;
	ct.off_x = 0.5f;
	ct.off_y = 0.5f;

	act.width = 1.0f;
}

VOID OnDestroy()
{
	action_destroy(&act);
	contour_destroy(&ct);
	shape_aa_destroy(&sp_aa);
	scanline_aa_destroy(&scl_aa);

	DeleteDC(hBmpDc);
	DeleteObject(hBmp);
}
VOID OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps = {0};
	HDC hdc = BeginPaint(hWnd, &ps);
	
	memset(bs.pbits, 0xFF, bs.length);

	action_reset(&act);
	contour_reset(&ct);
	shape_aa_reset(&sp_aa);
	shape_aa_set_clip(&sp_aa, 0, 800, 0, 600);
	ct.outter_join = line_join_bevel;
	ct.miter_limit = 2;

	int_32 count = 8;
	float_32 _xy[] = {100, 380, 180, 220, 260, 380, 340, 220, 420, 380, 500, 220, 580, 380, 660, 220};
	bsline_bsline(&act.base, _xy, 2, count, 1.0f, 0, command_move);

	action_add(&act, 10, 300, command_move);
	action_add(&act, 700, 300, command_line);

	action_to_contour(&act, &ct);
	contour_to_shape_aa(&ct, &sp_aa);
	if(wire)
		shape_aa_draw_test(&sp_aa, &scl_aa, &bs.buffer);
	else
		shape_aa_draw(&sp_aa, &scl_aa, &bs.buffer);

	BitBlt(hdc, 0, 0, WIDTH, HEIGHT, hBmpDc, 0, 0, SRCCOPY);
	EndPaint(hWnd, &ps);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_LBUTTONDOWN:
		SetCapture(hWnd);
		break;
	case WM_LBUTTONUP:
		ReleaseCapture();
		break;
	case WM_KILLFOCUS:
		break;
	case WM_RBUTTONDOWN:
		break;
	case WM_MOUSEMOVE:
		break;
	case WM_ERASEBKGND:
		break;
	case WM_CREATE:
		OnCreate();
		break;
	case WM_DESTROY:
		OnDestroy();
		PostQuitMessage(0);
		break;
	case WM_PAINT:
		OnPaint(hWnd);
		break;
	case WM_KEYDOWN:
		switch(wParam)
		{
		case VK_NUMPAD9:
			act.width += 1.0f;
			break;
		case VK_NUMPAD6:
			act.width -= 1.0f;
			break;
		case VK_F4:
			wire = !wire;
			break;
		default:
			return 0;
		}
		InvalidateRect(hWnd, NULL, FALSE);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
